/*******************************************************************************
 * Copyright (c) 2012 Tecnalia. Software Systems Engineering Unit.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@tecnalia.com)
 *     
 *******************************************************************************/
package es.esi.gemde.modeltransformator.ui.actions;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;

import es.esi.gemde.core.utils.GEMDEUtils;
import es.esi.gemde.modeltransformator.ModelTransformatorPlugin;
import es.esi.gemde.modeltransformator.exceptions.NoPreviousTransformationException;
import es.esi.gemde.modeltransformator.exceptions.TransformationEngineException;


/**
 * Action that executes the last transformation successfully launched by the Transformation Service
 *
 * @author Adrian Noguero (adrian.noguero@tecnalia.com)
 * @version 1.0
 * @since 1.0
 *
 */
public class ExecuteLastTransformationAction implements IWorkbenchWindowActionDelegate {
	private IWorkbenchWindow window;
	
	boolean errors = false;
	Exception caughtException = null;
	IStatus results = null;
	
	/**
	 * The constructor.
	 */
	public ExecuteLastTransformationAction() {
	}

	/**
	 * The action has been activated. The argument of the
	 * method represents the 'real' action sitting
	 * in the workbench UI.
	 * @see IWorkbenchWindowActionDelegate#run
	 */
	public void run(IAction action) {
		
		errors = false;
		try {
			ProgressMonitorDialog dialog = new ProgressMonitorDialog(window.getShell());
			dialog.run(true, false, new IRunnableWithProgress(){ 
				
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					try {
						monitor.beginTask("Executing the transformation...", IProgressMonitor.UNKNOWN);
						results = ModelTransformatorPlugin.getService().executeLastTransformation();
					}
					catch (NoPreviousTransformationException e) {
						// Should never occur!!
						caughtException = e;
						errors = true;
					} catch (TransformationEngineException e) {
						caughtException = e;
						e.printStackTrace();
						errors = true;
					}
					finally {
						monitor.done();
					}
					
				}
			});
		} catch (InvocationTargetException e1) {
			// Not relevant
			e1.printStackTrace();
		} catch (InterruptedException e1) {
			// Not relevant
			e1.printStackTrace();
		}
		
		if (errors) {
			MessageDialog.openError(new Shell(), "Exception occurred!", "The transformation couldn't be completed because an exception was raised:\n" + caughtException.getMessage().replaceAll("\r", ""));
			return;
		}
		if (results != null && !results.isOK()) {
			MessageDialog.openError(new Shell(), "Transformation returned error!", "The transformation engine returned an error:\n" + results.getMessage());
			return;
		}
		MessageDialog.openInformation(new Shell(), "Transformation completed!!", "The transformation was completed.");
		GEMDEUtils.refreshWorkspace();
	}

	/**
	 * Selection in the workbench has been changed. We 
	 * can change the state of the 'real' action here
	 * if we want, but this can only happen after 
	 * the delegate has been created.
	 * @see IWorkbenchWindowActionDelegate#selectionChanged
	 */
	public void selectionChanged(IAction action, ISelection selection) {
	}

	/**
	 * We can use this method to dispose of any system
	 * resources we previously allocated.
	 * @see IWorkbenchWindowActionDelegate#dispose
	 */
	public void dispose() {
	}

	/**
	 * We will cache window object in order to
	 * be able to provide parent shell for the message dialog.
	 * @see IWorkbenchWindowActionDelegate#init
	 */
	public void init(IWorkbenchWindow window) {
		this.window = window;
	}
}